#include "ExpAST.h"
#include "Globe.h"
#include <iostream>
#include "parser.h"
#include "Globe.h"
#pragma warning(disable:4267)
using std::cout;
using std::endl;

unique_ptr<BaseExpAST> parser::parseLAndExp()
{
    unique_ptr<BaseExpAST>l = this->parseOrExp();
    while (this->lexer->next_token() == TOK::LAND)
    {
        unique_ptr<LAndAST>t(new LAndAST);
        t->op = true;
        this->lexer->match(TOK::LAND);
        t->exp1 = std::move(l);
        t->exp2 = this->parseOrExp();
        l = std::move(t);
        t = nullptr;
    }
    return l;
}

void LAndAST::Dump() const
{
    cout << "{\"type\":\"LAnd\",\"op\":\"";
    switch (this->op)
    {
    case true:
        cout << "&&";
        break;
    default:break;
    }
    cout << "\"";
    if (this->op == false)
    {
        cout << "\"content\":";
        this->exp1->Dump();
    }
    else
    {
        cout << "\"exp1\":";
        this->exp1->Dump();
        cout << ",\"exp2\":";
        this->exp2->Dump();
    }
    cout << "}";
}


bool LAndAST::is_lval() const
{
    if (this->op == false)
        return this->exp1->is_lval();
    return false;
}

void LAndAST::Analyze() const
{
    if (this->op == false)
        this->exp1->Analyze();
    else
    {
        this->exp1->Analyze();
        size_t jump_tag_0 = ++jump_tag;
        GENASM(cmd_code::CMP, CVR(EAX), cmd_val(cmd_val::INTEGER, 0, 0));
        GENASM(cmd_code::JE, CVI(jump_tag_0), cmd_val());
        this->exp2->Analyze();
        GENASM(cmd_code::CMP, CVR(EAX), cmd_val(cmd_val::INTEGER, 0, 0));
        GENASM(cmd_code::JE, CVI(jump_tag_0), cmd_val());
        GENASM(cmd_code::MOV, CVI(1), CVR(EAX));
        size_t jump_tag_1 = ++jump_tag;
        GENASM(cmd_code::JMP, CVI(jump_tag_1), cmd_val());
        GENASM(cmd_code::FLAG, CVI(jump_tag_0), cmd_val());
        GENASM(cmd_code::MOV, CVI(0), CVR(EAX));
        GENASM(cmd_code::FLAG, CVI(jump_tag_1), cmd_val());
    }
}
